package com.witsight.platform.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.witsight.platform.annotation.logging.Logging;
import com.witsight.platform.util.lang.StringUtil;
import com.witsight.platform.util.tools.MessageUtil;

/**   
 * 说明：Log4j2日志切面
 * @Title: Log4j2Aspect.java 
 * @Package com.witsight.platform.aspect 
 * @See: {@link #Log4j2Aspect()}<br/>
 * Copyright: Copyright (c) 2017<br/>
 * Company:sany huax witsight team by product
 * @author: penght  
 * @date: 2017年10月31日 上午10:43:58 
 * @version: V1.0
 *
 */
public abstract class LoggingAspect {
	// 公共日志对象
	private final Logger log = LoggerFactory.getLogger(getClass());
	// 本地线程，记录时间
	protected final ThreadLocal<Long> startTime = new ThreadLocal<>();
	
	/**
	 * 
	 * 说明：定义切面的抽象方法
	 * @Title: log4j2
	 * @See: {@link #log4j2()}
	 * @author penght 
	 * @date: 2017年10月31日 上午10:45:36
	 */
	public abstract void logging();

	@Before("logging()")
	public void doBefore(JoinPoint joinPoint) throws Throwable {
		startTime.set(System.currentTimeMillis());
		String content = MessageUtil.getMessage("aspect.logging.method.start");
		content = StringUtil.replace(content, "#", "{}");
		// 处理完请求，返回内容
		writeLog(joinPoint, content);
	}

	@AfterReturning(returning = "ret", pointcut = "logging()")
	public void doAfterReturning(JoinPoint joinPoint, Object ret) throws Throwable {
		String content = MessageUtil.getMessage("aspect.logging.method.finish", 
				new Object[]{ret, (System.currentTimeMillis() - startTime.get())});
		content = StringUtil.replace(content, "#", "{}");
		// 处理完请求，返回内容
		writeLog(joinPoint, content);
	}

	@AfterThrowing(throwing="ex",pointcut = "logging()")
	public void doAfterThrowing(JoinPoint joinPoint, Throwable ex) throws Throwable {
		String content = MessageUtil.getMessage("aspect.logging.method.exception");
		content = StringUtil.replace(content, "#", "{}");
		// 处理完请求，返回内容
		writeLog(joinPoint, content, ex);
	}

	/**
	 * 
	 * 说明：取得日志对象
	 * @Title: getLogger
	 * @See: {@link #getLogger(Class)}
	 * @author penght
	 * @param clazz 输出的class 
	 * @return org.apache.logging.log4j.Logger 
	 * @date: 2016年10月11日 上午9:05:55
	 */
	protected Logger getLogger(Class<?> clazz) {
		if (clazz == null) {
			return log;
		}
		return LoggerFactory.getLogger(clazz);
	}
	/**
	 * 
	 * 说明：记录日志
	 * @Title: writeLog
	 * @See: {@link #writeLog(JoinPoint, String)}
	 * @author penght
	 * @param joinPoint 切面点
	 * @param content 自定义内容
	 * @throws SecurityException  权限异常
	 * @throws NoSuchMethodException  没有方法异常
	 * @date: 2016年10月11日 下午2:49:14
	 */
	protected void writeLog (JoinPoint joinPoint , String content) throws Throwable {
		this.writeLog(joinPoint,content,null);
	}

	/**
	 * 
	 * 说明：记录日志
	 * @Title: writeLog
	 * @See: {@link #writeLog(JoinPoint, String, Throwable)}
	 * @author penght
	 * @param joinPoint 切面点
	 * @param content 自定义内容
	 * @param ex 捕捉的异常
	 * @throws SecurityException 权限异常
	 * @throws NoSuchMethodException 没有方法异常
	 * @date: 2016年10月11日 下午2:49:39 
	 */
	protected abstract void writeLog(JoinPoint joinPoint , String content, Throwable ex ) throws Throwable;
	/**
	 * 
	 * 说明：取得class的内容
	 * @Title: getClassLogContent
	 * @See: {@link #getClassLogContent(Class)}
	 * @author penght
	 * @param clazz 切面的class
	 * @return 日志内容
	 * @date: 2016年10月11日 下午3:11:29
	 */
	protected String getClassLogContent(Class<?> clazz) {
		if (clazz == null) {
			return "";
		}
		Logging logging = (Logging) clazz.getAnnotation(Logging.class);
		if (logging != null) {
			return logging.value();
		}

		return "";
	}
}
